package com.tianji.learning.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.api.client.remark.LikedClient;
import com.tianji.api.client.user.UserClient;
import com.tianji.api.dto.user.UserDTO;
import com.tianji.api.vo.ReplyVO;
import com.tianji.common.autoconfigure.mq.RabbitMqHelper;
import com.tianji.common.constants.MqConstants;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.exceptions.ForbiddenException;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.dto.ReplyDTO;
import com.tianji.learning.domain.po.InteractionQuestion;
import com.tianji.learning.domain.po.InteractionReply;
import com.tianji.learning.domain.query.ReplyPageQuery;
import com.tianji.learning.domain.vo.QuestionVO;
import com.tianji.learning.mapper.InteractionReplyMapper;
import com.tianji.learning.service.IInteractionQuestionService;
import com.tianji.learning.service.IInteractionReplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 互动问题的回答或评论 服务实现类
 * </p>
 *
 * @author whx
 * @since 2024-12-03
 */
@Service
public class InteractionReplyServiceImpl extends ServiceImpl<InteractionReplyMapper, InteractionReply> implements IInteractionReplyService {

    @Autowired
    private IInteractionQuestionService interactionQuestionService;

    @Autowired
    private LikedClient likedClient;

    @Autowired
    private RabbitMqHelper mqHelper;

    @Override
    public PageDTO<ReplyVO> pageReplies(ReplyPageQuery replyPageQuery) {
        Page<InteractionReply> page = replyPageQuery.toMpPage();

        this.lambdaQuery()
                .select()
                .eq(ObjectUtil.isNotNull(replyPageQuery.getQuestionId()), InteractionReply::getQuestionId, replyPageQuery.getQuestionId())
                .eq(InteractionReply::getAnswerId, replyPageQuery.getAnswerId() == null ? 0 : replyPageQuery.getAnswerId())
                .eq(InteractionReply::getHidden, false)
                .orderByDesc(InteractionReply::getCreateTime)
                .page(page);

        PageDTO<ReplyVO> replyVOPage = PageDTO.of(page, ReplyVO.class);

        List<Long> ids = replyVOPage.getList().stream().map(ReplyVO::getId).collect(Collectors.toList());

        List<Long> likedIds = likedClient.likedBizList(ids);

        if(CollUtils.isNotEmpty(likedIds)){
            List<ReplyVO> collect = replyVOPage.getList()
                    .stream()
                    .peek(reply -> {
                        if (likedIds.contains(reply.getId())) {
                            reply.setLiked(true);
                        }
                    })
                    .collect(Collectors.toList());

            replyVOPage.setList(collect);
        }



        return replyVOPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addReply(ReplyDTO dto) {
        // 判断问题id是否存在
        if(ObjectUtil.isNotNull(dto.getQuestionId())){
            QuestionVO questionVO = interactionQuestionService.getQuestionById(dto.getQuestionId());

            if(ObjectUtil.isNull(questionVO)){
                throw new ForbiddenException("该问题不存在");
            }
        }

        // 判断回复id是否存在
        if(ObjectUtil.isNotNull(dto.getAnswerId())){
            InteractionReply interactionReply = this.lambdaQuery()
                    .eq(InteractionReply::getId, dto.getAnswerId())
                    .one();

            if(ObjectUtil.isNull(interactionReply)){
                throw new ForbiddenException("该回复不存在");
            }
        }

        InteractionReply interactionReply = BeanUtils.toBean(dto, InteractionReply.class);

        Long userId = UserContext.getUser();

        interactionReply.setUserId(userId);

        save(interactionReply);

        if(ObjectUtil.isNotNull(dto.getQuestionId()) && ObjectUtil.isNull(dto.getAnswerId())) {
            // 问题id存在
            // 问题字段的回答数量 +1 | latest_answer_id
            interactionQuestionService.updateQuestionLatestAnswerId(dto.getQuestionId(), interactionReply.getId());

        }else {
            // 评论id存在
            // 回复字段的评论数量 +1
            InteractionReply targetReply = getById(interactionReply.getTargetReplyId());

            if(ObjectUtil.isNull(targetReply)){
                throw new ForbiddenException("目标回复对象不存在");
            }
            this.lambdaUpdate()
                    .eq(InteractionReply::getId, interactionReply.getTargetReplyId())
                    .set(InteractionReply::getReplyTimes, targetReply.getReplyTimes() + 1)
                    .update();

            // 发送增加积分的异步请求
            mqHelper.send(
                    MqConstants.Exchange.LEARNING_EXCHANGE,
                    MqConstants.Key.LEARN_SECTION,
                    userId
            );
        }

        // 老师评论
        if(!dto.getIsStudent()){
            // 问题字段的回答数量 +1
            // 更新问题为已查看
            interactionQuestionService.lambdaUpdate()
                    .eq(InteractionQuestion::getId, dto.getQuestionId())
                    .set(InteractionQuestion::getStatus, 1)
                    .update();
        }

    }

    @Autowired
    private UserClient userClient;

    @Override
    public PageDTO<ReplyVO> pageRepliesForAdmin(ReplyPageQuery query) {

        Page<InteractionReply> page = query.toMpPage();

        this.lambdaQuery()
                .eq(InteractionReply::getAnswerId, query.getAnswerId()==null ? 0 : query.getAnswerId())
                .eq(ObjectUtil.isNotNull(query.getQuestionId()), InteractionReply::getQuestionId, query.getQuestionId())
                .page(page);

        List<InteractionReply> records = page.getRecords();

        List<ReplyVO> collect = records.stream().map(ir -> {
            List<Long> ids = Arrays.asList(ir.getUserId(), ir.getTargetUserId());

            List<UserDTO> userDTOS = userClient.queryUserByIds(ids);
            UserDTO userInfo;
            UserDTO replyUserInfo;
            if(userDTOS.size() == 1){
                 userInfo = userDTOS.get(0);
                 replyUserInfo = userDTOS.get(0);
            }else {
                 userInfo = userDTOS.get(0);
                 replyUserInfo = userDTOS.get(1);
            }

            ReplyVO replyVO = BeanUtils.toBean(ir, ReplyVO.class);
            replyVO.setUserName(userInfo.getName());
            replyVO.setUserIcon(userInfo.getIcon());

            replyVO.setTargetUserName(replyUserInfo.getName());

            return replyVO;
        }).collect(Collectors.toList());

        Page<ReplyVO> newPage = query.toMpPageDefaultSortByCreateTimeDesc();
        BeanUtil.copyProperties(page, newPage);

        return PageDTO.of(page, collect, newPage.getTotal());
    }

    @Override
    public void isHidden(Long id, Boolean hidden) {
        InteractionReply interactionReply = getById(id);

        if(ObjectUtil.isNull(interactionReply)){
            throw new ForbiddenException("该回复不存在");
        }

        if(interactionReply.getHidden() == hidden){
            if(hidden){
                throw new ForbiddenException("that reply have been hidden");
            }else {
                throw new ForbiddenException("that reply is still showing");
            }
        }

        this.lambdaUpdate()
                .eq(InteractionReply::getId, id)
                .set(InteractionReply::getHidden, hidden)
                .update();
    }
}
